package design.mode.dispatcher.util;

import design.mode.dispatcher.annotation.NotNullField;
import org.thymeleaf.util.MapUtils;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ParamValid {
    public static void notNullFieldValid(Object object, Integer... index) {
        if (null == object) {
            throw new RuntimeException("请求入参不能为:[null]");
        }
        Map<Integer, Integer> indexMap = new HashMap<>();
        //填充index索引
        getIndexMap(indexMap, index);
        //字符串类型校验
        validStrValue(object, "请求入参不能为空...");
        //map类型校验
        validMapValue(object);
        //Object对象类型校验
        validObjectValue(object, indexMap, index);

    }

    private static void validObjectValue(Object object, Map<Integer, Integer> indexMap, Integer[] index) {
        Class<?> clazz = object.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(NotNullField.class)) {
                try {
                    NotNullField annotation = field.getAnnotation(NotNullField.class);
                    int[] arr = annotation.index();
                    for (int i = 0; i < arr.length; i++) {
                        if (indexMap.containsKey(arr[i])) {
                            Object value = field.get(object);
                            if (null == value) {
                                throw new RuntimeException(annotation.message());
                            }
                            validStrValue(value, annotation.message());
                            if (value instanceof List) {
                                List list = (List) value;
                                if (list.size() <= 0) {
                                    throw new RuntimeException(annotation.message());
                                }

                                Map reqMap = (Map) value;
                                if (MapUtils.isEmpty(reqMap)) {
                                    throw new RuntimeException(annotation.message());
                                }

                                for (Object listObj : list) {
                                    notNullFieldValid(listObj, index);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e.getMessage());
                }
            }
        }
    }

    private static void validMapValue(Object object) {
        if (object instanceof Map) {
            Map map = (Map) object;
            for (Object obj : map.keySet()) {
                Object value = map.get(obj);
                if (null == value) {
                    throw new RuntimeException("请求入参:[" + obj + "]不能为空...");
                }
                validStrValue(value, "请求入参:[" + value + "]不能为空...");
            }
        }
    }

    private static void validStrValue(Object object, String s) {
        if (object instanceof String) {
            String value = (String) object;
            if (value.length() <= 0) {
                throw new RuntimeException(s);
            }
        }
    }

    private static void getIndexMap(Map<Integer, Integer> indexMap, Integer[] index) {
        if (index.length <= 0) {
            indexMap.put(0, null);
        } else {
            indexMap.putAll(Arrays.stream(index).collect(Collectors.toMap(Integer -> Integer, Integer -> Integer)));
        }
    }
}
